package com.idsmanager.oauth.domain.oauth;


import com.idsmanager.commons.utils.DateUtils;
import com.idsmanager.commons.utils.UUIDGenerator;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.Date;

/**
 * @author Shengzhao Li
 */
@Document(collection = "OauthClientDetails")
public class OauthClientDetails implements Serializable {


    private static final long serialVersionUID = 2430342715989473586L;
    @Id
    private String clientId = UUIDGenerator.generate();
    @CreatedDate
    private Date createTime = DateUtils.now();
    @Version
    private Long version;


    private boolean archived = false;

    private String resourceIds;

    private String clientSecret;

    private String scope;

    private String authorizedGrantTypes;

    private String webServerRedirectUri;

    private String authorities;

    private Integer accessTokenValidity;

    private Integer refreshTokenValidity;

    private String additionalInformation;

    private boolean trusted = false;

    public Date createTime() {
        return createTime;
    }

    public OauthClientDetails() {
    }

    public ClientDetails toClientDetails() {
        BaseClientDetails clientDetails = new BaseClientDetails(clientId, resourceIds, scope, authorizedGrantTypes, authorities, webServerRedirectUri);
        clientDetails.setClientSecret(clientSecret);

        if (StringUtils.hasText(additionalInformation)) {
            clientDetails.addAdditionalInformation("information", additionalInformation);
        }
        clientDetails.setAccessTokenValiditySeconds(accessTokenValidity);
        clientDetails.setRefreshTokenValiditySeconds(refreshTokenValidity);

        return clientDetails;
    }

    public boolean trusted() {
        return trusted;
    }

    public boolean archived() {
        return archived;
    }

    public OauthClientDetails clientId(String clientId) {
        this.clientId = clientId;
        return this;
    }

    public OauthClientDetails additionalInformation(String additionalInformation) {
        this.additionalInformation = additionalInformation;
        return this;
    }


    public OauthClientDetails authorities(String authorities) {
        this.authorities = authorities;
        return this;
    }

    public OauthClientDetails clientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
        return this;
    }

    public OauthClientDetails resourceIds(String resourceIds) {
        this.resourceIds = resourceIds;
        return this;
    }

    public OauthClientDetails authorizedGrantTypes(String authorizedGrantTypes) {
        this.authorizedGrantTypes = authorizedGrantTypes;
        return this;
    }

    public OauthClientDetails scope(String scope) {
        this.scope = scope;
        return this;
    }


    public String clientId() {
        return this.clientId;
    }

    public String webServerRedirectUri() {
        return this.webServerRedirectUri;
    }

    public String authorities() {
        return this.authorities;
    }

    public Integer accessTokenValidity() {
        return this.accessTokenValidity;
    }

    public Integer refreshTokenValidity() {
        return this.refreshTokenValidity;
    }

    public String clientSecret() {
        return this.clientSecret;
    }

    public String scope() {
        return scope;
    }

    public String resourceIds() {
        return resourceIds;
    }

    public String additionalInformation() {
        return this.additionalInformation;
    }

    public String authorizedGrantTypes() {
        return this.authorizedGrantTypes;
    }

    public OauthClientDetails accessTokenValidity(Integer accessTokenValidity) {
        this.accessTokenValidity = accessTokenValidity;
        return this;
    }

    public OauthClientDetails refreshTokenValidity(Integer refreshTokenValidity) {
        this.refreshTokenValidity = refreshTokenValidity;
        return this;
    }

    @Override
    public String toString() {
        return "{" +
                "clientId='" + clientId + '\'' +
                ", createTime=" + createTime +
                ", version=" + version +
                ", archived=" + archived +
                ", resourceIds='" + resourceIds + '\'' +
                ", scope='" + scope + '\'' +
                ", authorizedGrantTypes='" + authorizedGrantTypes + '\'' +
                ", authorities='" + authorities + '\'' +
                ", trusted=" + trusted +
                ", accessTokenValidity=" + accessTokenValidity +
                '}';
    }
}
